分类
联系方式
  1. 新浪微博
  2. E-mail

Objective-C 类

介绍

在 OC 中使用 @interface 关键字声明一个类:

@interface MyClass : NSObject
{
    int         count;
    id          data;
    NSString*   name;
}

- (id)initWithString:(NSString*)aName;
+ (MyClass*)myClassWithString:(NSString*)aName;
@end

实现类:

#import "Student.h"
 
@implementation Student
 
-(void) printInfo
{
    NSLog(@"姓名:%@ 年龄:%d岁",studentName,studentAge);
}
-(void) setStudentName: (NSString*) name
{
    studentName = name;
}

@end

创建一个类

在 XCode 中,File - New - File,选择 Cocoa,选择 Objective-C 类。类名输入 BNRPerson,继承自 NSObject。

项目中将会创建两个文件 BNRPerson.m 和 BNRPerson.h。在 BNRPerson.h 中,包含两个成员变量:

#import <Foundation/Foundation.h>

@interface BNRPerson : NSObject

{
    float _heightInMeters;
    int _weightInKilos;
}

- (float)heightInMeters;
- (void)setHeightInMeters:(float)h;
- (int)weightInKilos;
- (void)setWeightInKilos:(int)w;

- (float)bodyMassIndex;

@end

头文件以 @interface 开始,以 @end 结尾。用下划线表示是否是私有成员。成员定义在花括号里,紧跟着是类方法。

在头文件和实现文件中切换的快捷键:Control-Command-up

BNRPerson.m 类实现:

#import "BNRPerson.h"

@implementation BNRPerson

- (float)heightInMeters
{
    return _heightInMeters;
}

- (void)setHeightInMeters:(float)h
{
    _heightInMeters = h;
}

- (int)weightInKilos
{
    return _weightInKilos;
}

- (void)setWeightInKilos:(int)w
{
    _weightInKilos = w;
}

- (float)bodyMassIndex
{
    return _weightInKilos / (_heightInMeters * _heightInMeters);
}

@end

这里的访问方法可以通过 properties 特性省略掉。

类方法

在 Objective-C 中,调用类方法,实际上是像这个类的实例发出一个调用方法的消息

消息使用方括号修饰,由两个部分组成:

  • 接收者(receiver)
  • 选择器(selector)

例如:

NSDate *now = [NSDate date];

其中:

  • NSDate 是接收者,拥有这个方法的类或对象
  • date 是选择器,指定要运行哪个方法

类方法怎么看:

类方法和实例方法

也就是静态方法和实例方法。

带参数的消息

单个参数示例:

[now dateByAddingTimeInterval:100000];

多个参数示例:

[cal ordinalityOfUnit:NSDayCalendarUnit
               inUnit:NSMonthCalendarUnit
              forDate:now];

参数分析:

这个方法包含 3 个参数,方法名分成 3 个部分,但这是一个消息,触发了一个方法。

A of B,这句话,inUnit 表示 B, ordinalityOfUnit 表示 A, forDate 表示被计算的对象。

嵌套消息发送

[[NSDate date] timeIntervalSince1970];

向 nil 发送消息

在 Objective-C 中不使用 NULL,而是用 nil,nil 表示不指向任何对象,都表示 zero 指针。

在 Objective-C 的设计中,允许向 nil 发送消息,结果只不过是什么都不发生。

alloc 和 init

alloc 用于创建类实例,返回指向新实例的指针。

此时这个实例还需要被初始化。未被初始化的实例,尽管内存分配了,但是还没有准备好接收消息。

init 方法用于对实例进行初始化。

这两个方法通常嵌套使用:

[[NSDate alloc] init];

类成员

可访问性

不指定默认都是 protected 的。

@interface Worker : NSObject
{
    char *name;
@private
    int age;
    char *evaluation;
@protected
    id job;
    float wage;
@public
    id boss;
}

创建类实例

Student *student = [[Student alloc]init];
    [student setStudentName:@"张三"];
    [student setAge:10];
    [student printInfo];
    [student release];

类属性

在 Objective-C 中,有一种名为属性(properties)的特性,能省掉声明实例变量,省掉实现访问方法。

实例代码如下:

#import <Foundation/Foundation.h>

@interface BNRPerson : NSObject

// 没有中括号了
@property (nonatomic) float heightInMeters;
@property (nonatomic) int weightInKilos;

……
@end

properties attributes

nonatomic 和 atomic

两个里面选择一个,与多线程相关。

readonly 和 readwrite

readonly 属性只读:

@property (nonatomic, readonly) double circumferenceOfEarth;

编译器只会创建 getter,但是不会创建 setter。 readwrite 可读可写:

@property (nonatomic, readwrite) double humanPopulation;

默认就是 readwrite,因此可以不写。

点语法

property 创建的 getter 和 setter 可以通过点语法进行访问:

mikey.weightInKilos = 96;
int weight = mikey.weightInKilos;

需要注意的是,点其实还是对 getter 和 setter 的方法调用,还会发送消息。


id

在很多时候需要创建一个指针,但是不知道它的具体类型是什么。这种情况下使用 id 类型,表示指向某种 Objective-C 对象的指针:

id delegate;